<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>loadrunner test</title>
    <link rel="stylesheet" href="../vendor/qunit/qunit.css" type="text/css" charset="utf-8">
    <script src="../vendor/qunit/qunit.js" type="text/javascript" charset="utf-8"></script>
  </head>
  <body>
    <h1 id="qunit-header">module.js test</h1>
    <h2 id="qunit-banner"></h2>
    <h2 id="qunit-userAgent"></h2>
    <ol id="qunit-tests"></ol>

    <script type="text/javascript" charset="utf-8">
     function runTests() {

        QUnit.module('script tag options');

         QUnit.test('should be able to set load path with data-path', function() {
           equal('modules', using.path);
         });

         QUnit.test('should load main if set with data-main', function() {
           ok(mainLoaded, 'main should be loaded');
         });

         QUnit.module('module');

         QUnit.test('should be able to define a module with an object literal', function() {
           expect(2);
           stop(200);

           provide('test', { a: 1, b: 'thing' }).then(function(mod) {
             equals(1, mod.a, 'exports.a set');
             equals('thing', mod.b, 'exports.b set');
             start();
           });
         });

         QUnit.test('should be able to define with a function', function() {
           var mod = provide('test2', function(exports) {
             exports({
               a: 1,
               b: 'thing'
             });
           });

           expect(2);
           stop(200);

           mod.then(function() {
             equals(mod.exports.a, 1, 'exports.a set');
             equals(mod.exports.b, 'thing', 'exports.b set');
             start();
           });
         });

       QUnit.module('require - file');

       QUnit.test('should require a single normal file', function() {
         expect(1);
         stop(1000);

         using('javascripts/e.js', function() {
           ok(loadedE, 'e.js was executed');
           start();
         });
       });

       QUnit.test('should require a file prefixed with $ from using.path', function() {
         expect(1);
         stop(1000);

         loadScript = false;

         using('$sub/script.js', function() {
           ok(loadScript, 'script.js was executed');
           start();
         });
       });

       QUnit.test('should require multiple files in parallel', function() {
         expect(2);
         stop(1000);

         using('javascripts/c.js', 'javascripts/d.js', function() {
           ok(loadedC, 'c.js was executed');
           ok(loadedD, 'd.js was executed');
           start();
         });
       });

       QUnit.test('should require a file only once', function() {
         expect(2);
         stop(1000);

         bLoadCount = 0;

         using('javascripts/b.js', function() {
           ok(bLoadCount, 'b.js was executed');

           using('javascripts/b.js', function() {
             equal(1, bLoadCount, 'b.js was not loaded again');
             start();
           });

         });
       });

       QUnit.module('require - module');

       QUnit.test('should require a module', function() {
         expect(1);
         stop(1000);

         using('moda', function(moda) {
           equals('success', moda.test, 'module exports loaded');
           start();
         });
       });

       QUnit.test('should require multiple modules', function() {
         expect(2);
         stop(1000);

         using('moda', 'modb', function(moda, modb) {
           equals('success', moda.test, 'moda exports loaded');
           equals('success', modb.test(), 'modb exports loaded');
           start();
         });
       });

       QUnit.test('should require modules that have a dependency', function() {
         expect(1);
         stop(1000);

         using('modc', function(modc) {
           equals('success from mod a', modc.test(), 'modc exports loaded');
           start();
         });
       });

       QUnit.test('should require modules that have nested dependencies', function() {
         expect(1);
         stop(1000);

         using('modd', function(modd) {
           equals('success from mod a via mod d', modd.test(), 'modd exports loaded');
           start();
         });
       });

       QUnit.test('should require modules that have dependencies on regular scripts', function() {
         expect(1);
         stop(1000);

         using('mode', function(mode) {
           ok(mode.test(), 'mode ensured d.js was loaded');
           start();
         });
       });

       QUnit.test('should require modules that are in subfolders', function() {
         expect(1);
         stop(1000);

         using('sub/modsubfolder', function(modsubfolder) {
           ok(modsubfolder.test(), 'mode ensured d.js was loaded');
           start();
         });
       });

       QUnit.test('should collect module results into a single parameter if requested', function() {
         expect(2);
         stop(1000);

         using('moda', 'modb').as(function(results) {
           equals('success', results.moda.test, 'moda exports loaded');
           equals('success', results.modb.test(), 'modb exports loaded');
           start();
         });
       });

       QUnit.test('should collect module results without overwriting namespaces', function() {
         expect(2);
         stop(1000);

         using('sub/submoda', 'sub/submodb').as(function(results) {
           equals('success', results.sub.submodb.test(), 'sub.submodb exports loaded');
           equals('success', results.sub.submoda.test, 'sub.submoda exports loaded');
           start();
         });
       });

       QUnit.module('Sequences');

       QUnit.test('should use dependencies in sequence if array argument', function() {
         window.testSeq = [];

         expect(1);
         stop(1000);

         using(['javascripts/s1.js', 'javascripts/s2.js', 'javascripts/s3.js'], function() {
           deepEqual(window.testSeq, [1,2,3], 'scripts executed in sequence');
           start();
         });
       });

       QUnit.test('should return modules in sequence if array argument', function() {
          expect(3);
          stop(1000);

          using('modb', ['moda', 'modb'], 'moda', function(modb2, moda, modb, moda2) {
            equals('success', moda.test, 'moda exports loaded from sequence');
            equals('success', modb.test(), 'modb exports loaded from sequence');
            equals('success', moda2.test, 'moda exports loaded outside sequence');
            start();
          });
        });

        QUnit.test('should return modules in sequence if nested array argument', function() {
           expect(3);
           stop(1000);

           using(['modb', ['moda', 'modb'], 'moda'], function(modb2, moda, modb, moda2) {
             equals('success', moda.test, 'moda exports loaded from sequence');
             equals('success', modb.test(), 'modb exports loaded from sequence');
             equals('success', moda2.test, 'moda exports loaded outside sequence');
             start();
           });
         });

       QUnit.test('should return collected modules if array argument', function() {
         expect(3);
         stop(1000);

         using('moda', ['moda', 'modb', 'sub/modsubfolder'], 'moda').as(function(results, dead) {
           equals('success', results.moda.test, 'moda exports loaded');
           equals('success', results.modb.test(), 'modb exports loaded');
           equals('truesuccess from mod a via mod d', results.sub.modsubfolder.test(), 'modb exports loaded');
           start();
         });
       });

       QUnit.test('should return collected modules if nested array argument', function() {
         expect(3);
         stop(1000);

         using(['moda', ['moda', 'modb', 'sub/modsubfolder']]).as(function(results) {
           equals('success', results.moda.test, 'moda exports loaded');
           equals('success', results.modb.test(), 'modb exports loaded');
           equals('truesuccess from mod a via mod d', results.sub.modsubfolder.test(), 'modb exports loaded');
           start();
         });
       });

        QUnit.module('LoadBuilder test');

        QUnit.test('should be able to provide module and use it, inline', function() {
          expect(1);
          stop(2000);

          provide('a/b', function(exports) {
            exports(true);
          });

          using('a/b', function(ab) {
            ok(ab);
            start();
          });
        });

        QUnit.test('should be able load several named modules in a single file', function() {
          expect(1);
          stop(2000);

          using('modcompiled', function(ab) {
            equals(ab, 'thinganother');
            start();
          });
        });

        QUnit.test('should put individual args after obj when using .as()', function() {
          expect(2);
          stop(2000);


          using('moda', 'modb').as(function(all, moda, modb) {
            ok(all.moda == moda);
            ok(all.modb == modb);
            start();
          });
        });

        QUnit.test('should be able load modules from a bundle', function() {
          expect(2);
          stop(2000);
          loadrunner.Script.loaded = [];
          using.bundles.push({ 'modules/modcompiled.js': ['thing', 'another'] });
          using('thing', 'another', function(a, b) {
            equals(a, 'thing');
            equals(b, 'another');
            start();
          });
        });

        QUnit.test('should only evaluate required modules from a bundle', function() {
          expect(3);
          stop(2000);
          loadrunner.reset();
          window.thingLoaded = false;
          equals(false, window.thingLoaded);
          using.bundles.push({ 'modules/modcompiled.js': ['thing', 'another'] });
          using('another', function(a) {
            equals(a, 'another');
            equals(false, window.thingLoaded);
            start();
          });
        });


        QUnit.module('Autofetch tests', {
          teardown: function() {
            loadrunner.reset();
            loadrunner.Script.autoFetch = true;
          }
        });

        QUnit.test('should be able to defer start of dep using autoFetch = false', function() {
          expect(1);
          stop(2000);
          loadrunner.Script.autoFetch = false;
          var startCalled = false;

          using('defered', function(a) {
            if (startCalled) {
              ok(a === 'loaded now', 'only loaded after start');
            } else {
              ok(false, 'loaded without start being called');
            }

            start();
          });

          setTimeout(function() {
            startCalled = true;
            using('defered').forceFetch();
          }, 100);
        });

        QUnit.test('should be able to defer start of dep, with a callback', function() {
          expect(1);
          stop(2000);
          loadrunner.Script.autoFetch = false;

          setTimeout(function() {

            using('defered2', function() {
              ok(true, "callback fired");

              start();
            }).forceFetch();

          }, 100);
        });

        QUnit.test('should still run provided modules immediately, despite autoFetch = false', function() {
          expect(1);
          stop(2000);
          loadrunner.Script.autoFetch = false;

          provide('laterz', function(exports) {
            exports('loaded now');
          });
          using('laterz', function(a) {
            ok(a === 'loaded now', 'failed to use provided module');

            start();
          });

        });

        QUnit.test('should be able to detect unprovided modules using debug', function() {
          expect(1);
          loadrunner.Script.autoFetch = false;

          using('neverheardofuz', function(a) {
          });
          ok(loadrunner.debug().paused['module_neverheardofuz'], 'Paused dependency found');
        });

        QUnit.module('Depth test');
        QUnit.test('should cope with a deep Sequence', function() {
         expect(1);
         stop(5000);

         using('deep', function(deep) {
           equals('success', deep, 'module exports loaded');
           start();
         });
        });
        QUnit.test('should cope with many identical module loads', function() {
         expect(1);
         stop(5000);

         using('many', function(many) {
           equals('success', many, 'module exports loaded');
           start();
         });
        });

        QUnit.module('Case test', {
          setup:function() {
            this.conlog = console.log;
          },
          teardown:function() {
            console.log = this.conlog;
          }
        });

        // QUnit.test('should warn about case sensitivity', function() {
        //   expect(2);
        //   stop(5000);
        //   console.log = function(msg) {
        //     ok(true, msg);
        //   }
        //
        //   using('moda', 'ModA', function(moda) {
        //     equals('success', moda.test, 'module exports loaded');
        //     start();
        //   });
        // });

     }
    </script>

    <script type="text/javascript" charset="utf-8">
      (function(){
          function indexOf(arr, thing) {
            for (var i=0, item; item = arr[i]; i++) {
              if (thing == item) {
                return i;
              }
            }

            return -1;
          }

          var a = document.createElement('script');
          a.type = 'text/javascript';
          a.async = true;
          a.src = location.search.match(/dist=true/) ? '../dist/loadrunner.js' : '../src/loadrunner.js';
          a.setAttribute('data-path', 'modules');
          a.setAttribute('data-main', 'javascripts/main.js');

          a.onload = runTests;

          a.onreadystatechange = function () {
            if (indexOf(['loaded', 'complete'], this.readyState) > -1) {
              this.onreadystatechange = null;
              this.onload = null;
              runTests();
            }
          };

          document.getElementById('qunit-header').innerHTML += ' (' + a.src.match(/(dist|src)/)[1] + ')';

          var s = document.getElementsByTagName('script')[0];
          s.parentNode.insertBefore(a, s);
      })();
    </script>
  </body>
</html>